package com.heima.media.service.impl;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.heima.common.aliyun.GreenImageScan;
import com.heima.common.aliyun.GreenTextScan;
import com.heima.common.dto.ResponseResult;
import com.heima.common.enums.AppHttpCodeEnum;
import com.heima.common.minio.MinIOService;
import com.heima.common.util.SensitiveWordUtil;
import com.heima.media.dto.ArticleDto;
import com.heima.media.dto.ContentDto;
import com.heima.media.dto.ImageDto;
import com.heima.media.entity.WmChannel;
import com.heima.media.entity.WmNews;
import com.heima.media.entity.WmSensitive;
import com.heima.media.entity.WmUser;
import com.heima.media.feign.ArticleFeign;
import com.heima.media.service.*;
import org.apache.commons.io.IOUtils;
import org.redisson.api.RBlockingQueue;
import org.redisson.api.RDelayedQueue;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import javax.print.DocFlavor;
import java.io.IOException;
import java.io.InputStream;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.function.Function;

@Service
public class AuditServiceImpl implements IAuditService {


    /**
     * 审核
     * @param wmNews
     */
    @Override
    @Async
    public void aduit(WmNews wmNews) {
        // 如果文章状态为8或4 4是人工审核通过
        if (wmNews.getStatus() == 4 || wmNews.getStatus() == 8) {
            if (System.currentTimeMillis() <= wmNews.getPublishTime().getTime()) {
                sendDalayMessage(wmNews);
            } else {
                saveArticle(wmNews);
            }
        }
        if(wmNews.getStatus()==1){
            //提取内容中文本内容和图片
           Map<String,Object> map= getTextAndImagesFromContent(wmNews.getContent());
          String text= (String)map.get("text");
          List<String> images= (List<String>) map.get("images");
          //先进行本地敏感词的一个匹配
          boolean sensResult=checkSens(wmNews,text);
            if(!sensResult)return;
          //阿里云审核内容
           boolean textResult= checkText(wmNews,text);
           if(!textResult)return;
           //有可能封面图片和内容图片不一样
            List<ImageDto> coberImages = JSON.parseArray(wmNews.getImages(), ImageDto.class);
            for (ImageDto image : coberImages) {
                if(!images.contains(image.getUrl())){
                    images.add(image.getUrl());
                }
            }
            //阿里云审核图片
           boolean imageResult= checkImage(wmNews,images);
            if(!imageResult)return;
            if(wmNews.getPublishTime().getTime()>System.currentTimeMillis()){
                sendDalayMessage(wmNews);
            }else{
                //调用文章微服务保存文章
                saveArticle(wmNews);
            }

        }
    }
    @Autowired
    private RedissonClient client;

    private void sendDalayMessage(WmNews wmNews) {
        wmNews.setStatus(8);
        newsService.updateById(wmNews);
        // 发送延迟消息
        RBlockingQueue<Object> blockingQueue = client.getBlockingQueue("article-publish");
        RDelayedQueue<Object> delayedQueue = client.getDelayedQueue(blockingQueue);
        // 延迟的长度为文章发布时间 - 当前系统时间
        Long time=wmNews.getPublishTime().getTime()-System.currentTimeMillis();
        delayedQueue.offer(wmNews,time, TimeUnit.MILLISECONDS);
    }

    @Autowired
    private IWmSensitiveService sensitiveService;
    
    /**
     *敏感词过滤
     * @param wmNews
     * @param text
     * @return
     */
    private boolean checkSens(WmNews wmNews, String text) {
        if(SensitiveWordUtil.dictionaryMap.size()==0){
            //初始花
            LambdaQueryWrapper<WmSensitive> query=new LambdaQueryWrapper<>();
            query.select(WmSensitive::getSensitives);
            List<String> words = sensitiveService.listObjs(query,o -> o.toString());
            SensitiveWordUtil.initMap(words);
        }
        //审核标题+标签+内容
        Map<String, Integer> map = SensitiveWordUtil.matchWords(wmNews.getTitle() + wmNews.getLabels() + text);
        if(map.size()>0){
            wmNews.setStatus(2);
            Set<String> keys = map.keySet();
            String join = String.join(",", keys);
            wmNews.setReason("敏感词不通过："+join);
            newsService.updateById(wmNews);
            return false;
        }
        return true;
    }

    @Autowired
    private IWmUserService userService;
    @Autowired
    private IChannelService channelService;

    @Autowired
    private ArticleFeign articleFeign;


    /**
     * 调用文章微服务保存文章
     * @param wmNews
     */
    private void saveArticle(WmNews wmNews) {
        ArticleDto dto=new ArticleDto();
        dto.setTitle(wmNews.getTitle());
        //从wm_user 查询作者信息
        WmUser wmUser = userService.getById(wmNews.getUserId());
        dto.setAuthorId(wmUser.getApAuthorId());
        dto.setAuthorName(wmUser.getName());
        dto.setChannelId(wmNews.getChannelId());
        dto.setLayout(wmNews.getType());
        //查询频道信息
        WmChannel wmChannel = channelService.getById(wmNews.getChannelId());
        dto.setChannelName(wmChannel.getName());
        dto.setFlag(0);
        //前端显示的图片地址
        List<ImageDto> list = JSON.parseArray(wmNews.getImages(), ImageDto.class);
        List<String> images=new ArrayList<>();
        for (ImageDto imageDto : list) {
            images.add(imageDto.getUrl());
        }
        String join = String.join(",", images);
        dto.setImages(join);
        dto.setContent(wmNews.getContent());
        dto.setLabels(wmNews.getLabels());
        dto.setPublishTime(wmNews.getPublishTime());
        ResponseResult<Long> longResponseResult = articleFeign.saveArticle(dto);
        if(longResponseResult.getCode().equals(AppHttpCodeEnum.SUCCESS.getCode())){
            Long articleId = longResponseResult.getData();
            if(articleId!=null){
                wmNews.setArticleId(articleId);
                wmNews.setStatus(9);
                newsService.updateById(wmNews);
            }
        }
    }

    @Autowired
    private GreenImageScan imageScan;
    @Autowired
    private MinIOService minIOService;


    /**
     * 图片审核
     * @param wmNews
     * @param images
     * @return
     */
    private boolean checkImage(WmNews wmNews, List<String> images) {
        boolean result=false;
        if(images.size()==0){
            return true;
        }
        try {
            List<byte[]> imageList=new ArrayList<>();
            for (String image : images) {
                if(!StringUtils.isEmpty(image)){
                    InputStream inputStream = minIOService.download(image);
                    byte[] bytes = IOUtils.toByteArray(inputStream);
                    imageList.add(bytes);
                }
            }
            Map map = imageScan.imageScan(imageList);
            String suggestion = (String) map.get("suggestion");
            switch (suggestion){
                case "pass":
                    result=true;
                    break;
                case "block":
                    //审核不通过
                    //修改文章状态
                    wmNews.setStatus(2);
                    wmNews.setReason("阿里云图片审核失败："+map.get("label"));
                    newsService.updateById(wmNews);
                    break;
                case "review":
                    //需要人工审核
                    //修改文章状态为3
                    wmNews.setStatus(3);
                    newsService.updateById(wmNews);
                    break;
            }

        } catch (Exception e) {
            e.printStackTrace();
        }
        return result;
    }

    @Autowired
    private GreenTextScan textScan;
    @Autowired
    private IWmNewsService newsService;


    /**
     * 审核内容
     * @param wmNews
     * @param text
     * @return
     */
    private boolean checkText(WmNews wmNews, String text) {
        boolean result=false;
        text=wmNews.getTitle()+wmNews.getLabels()+text;
        try {
            Map map = textScan.greenTextScan(text);
            String suggestion = (String) map.get("suggestion");
            switch (suggestion){
                case "pass":
                    result=true;
                    break;
                case "block":
                    //审核不通过
                    //修改文章状态
                    wmNews.setStatus(2);
                    wmNews.setReason("阿里云审核失败："+map.get("label"));
                    newsService.updateById(wmNews);
                    break;
                case "review":
                    //需要人工审核
                    //修改文章状态为3
                    wmNews.setStatus(3);
                    newsService.updateById(wmNews);
                    break;
            }

        } catch (Exception e) {
            e.printStackTrace();
        }
        return result;
    }

    /**
     * 提取内容中的文本内容和图片内容
     *
     * @param content
     * @return
     */
    private Map<String, Object> getTextAndImagesFromContent(String content) {
        Map<String, Object> map = new HashMap<>();
        StringBuilder sb = new StringBuilder();
        List<String> images = new ArrayList<>();
        List<ContentDto> dtos = JSON.parseArray(content, ContentDto.class);
        for (ContentDto dto : dtos) {
            if (dto.getType().equals("text")) {
                // 添加到文本内容
                sb.append(dto.getValue());
            } else {
                // 添加到图片集合
                if (!StringUtils.isEmpty(dto.getValue())) {
                    images.add(dto.getValue());
                }
            }
        }
        map.put("text", sb.toString());
        map.put("images", images);
        return map;
    }
}
